package net.lahuobao.util;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.*;

/**
 * Created by Frank on 1/27/2015.
 */
public class CacheMgr {
    private Logger logger = Logger.getLogger("CacheMgr");
    private JedisPool pool = null;

    private JedisPool getPool() {
        if (pool == null) {
            // 从配置文件中获取服务器IP地址
            ResourceBundle bundle = PropertyResourceBundle.getBundle("web");
            String cacheServer = bundle.getString("cache_server");
            JedisPoolConfig poolConfig = new JedisPoolConfig();
            pool = new JedisPool(poolConfig, cacheServer);
        }
        return pool;
    }

    /*
    private void returnResource(JedisPool pool, Jedis redis) {
        if (redis != null) {
            pool.returnResource(redis);
        }
    }*/

    public void set(String key, String value) {
        // 不设置缓存 一小时
        set(key, value, 3600);
    }

    /*
    * 缓存Key
    * 缓存 数据
    * 过期时间，单位秒
    * */
    public void set(String key, String value, int expire) {
        JedisPool pool = null;
        Jedis jedis = null;
        try {
            pool = getPool();
            jedis = pool.getResource();
            value = jedis.set(key, value);

            if (expire > 0) {
                jedis.expire(key, expire);
            }
            //返还到连接池
            pool.returnResource(jedis);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            logger.error("set key:" + key, e);
        }
    }

    public void setCollection(String key, ArrayList list) {
        // 不设置缓存 一小时
        JSONArray jsonArray = JSONArray.fromObject(list);
        set(key, jsonArray.toString(), 3600);
    }

    /*
   * 缓存Key
   * 缓存 数据
   * 过期时间，单位秒
   * */
    public void setCollection(String key, ArrayList list, Integer expire) {
        JSONArray jsonArray = JSONArray.fromObject(list);
        set(key, jsonArray.toString(), expire);
    }

    public long getExpire(String key) {
        JedisPool pool = null;
        Jedis jedis = null;
        long expire = new Long(-1);
        try {
            pool = getPool();
            jedis = pool.getResource();
            expire = jedis.ttl(key);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            logger.error("set key:" + key, e);
        }
        return expire;
    }

    /*
    * 保存 Map 对象到redis
    * */
    private void set(String key, HashMap<String, String> map, int expire) {
        JedisPool pool = null;
        Jedis jedis = null;
        try {
            pool = getPool();
            jedis = pool.getResource();
            jedis.hmset(key, map);

            if (expire > 0) {
                jedis.expire(key, expire);
            }
            //返还到连接池
            pool.returnResource(jedis);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            logger.error("set key:" + key, e);
        }
    }


    public void setMap(String key, HashMap<String, Object> map) {
        // 获取map中的对象转换成json字符串重新在保存到redis中
        HashMap<String, String> stringMap = new HashMap<String, String>();
        Set set = map.keySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            String mapKey = (String) iterator.next();
            Object object = map.get(mapKey);
            JSONObject jsonObject = JSONObject.fromObject(object);
            stringMap.put(mapKey, jsonObject.toString());
        }
        set(key, stringMap, -1);
    }


    public String get(String key) {
        String value = null;

        JedisPool pool = null;
        Jedis jedis = null;
        try {
            pool = getPool();
            jedis = pool.getResource();
            value = jedis.get(key);
            //返还到连接池
            pool.returnResource(jedis);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            logger.error("get key:" + key, e);
        }
        return value;
    }

    /*
    * 获取保存在redis map 中的对象
    * */
    private List<String> get(String key, String... mapKeys) {
        List<String> values = null;
        JedisPool pool = null;
        Jedis jedis = null;
        try {
            pool = getPool();
            jedis = pool.getResource();
            values = jedis.hmget(key, mapKeys);

            //返还到连接池
            pool.returnResource(jedis);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            logger.error("set key:" + key, e);
        }
        return values;
    }

    /*
    *  获取集合
    * */
//    public Collection getCollection(String key, Class objectClass) {
//        // 如果key不存在返回 null
//        String json = get(key);
//        if (StringUtils.isEmpty(json)) {
//            return null;
//        }
//
//        Collection collection = JSONArray.toCollection(jsonArray, objectClass);
//        return collection;
//    }


    /*
    * 获取map中的对象列表
    * */
    public ArrayList<Object> getMap(String key, Class beanClass, String... mapKeys) {
        ArrayList<Object> objectList = new ArrayList<Object>();
        List<String> stringList = get(key, mapKeys);
        for (String string : stringList) {
            JSONObject jsonObject = JSONObject.fromObject(string);
            Object object = JSONObject.toBean(jsonObject, beanClass);
            objectList.add(object);
        }
        return objectList;
    }

    public long del(String key) {
        long result = 0;

        JedisPool pool = null;
        Jedis jedis = null;
        try {
            pool = getPool();
            jedis = pool.getResource();
            jedis.del(key);
            //返还到连接池
            pool.returnResource(jedis);
        } catch (Exception e) {
            //释放redis对象
            pool.returnBrokenResource(jedis);
            e.printStackTrace();
            logger.error("get key:" + key, e);
        }
        return result;
    }


    /***
     * 发布消息到指定频道
     * @param channel       频道名称
     * @param message       消息
     * @return
     */
    public boolean pulish(String channel,String message){
        boolean bool = false;
        Jedis jedis = null;
        try{
            jedis = getPool().getResource();
            jedis.publish(channel,message);
            bool = true;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(jedis != null){
                getPool().returnBrokenResource(jedis);
            }
        }
        return bool;
    }
}
